package com.tools
{
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.geom.Point;
	import flash.globalization.DateTimeStyle;
	import flash.net.URLRequest;
	import flash.net.registerClassAlias;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.xml.XMLDocument;
	import flash.xml.XMLNode;

	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	import mx.formatters.DateFormatter;
	import mx.rpc.xml.SimpleXMLEncoder;

	import spark.formatters.DateTimeFormatter;

	/**
	 * 工具类
	 * @author Boder
	 * @Time 2011-8-27 9:31:44
	 */
	public class ToolsHelper
	{
		private static const chineseLevel2Mapping : Array = ["", "万", "亿", "兆"]
		private static const chineseLevelMapping : Array  = ["", "十", "百", "千"]
		private static const chineseMapping : Array       = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];

		private static const punctuationMapping : Array   = [[",", ".", ":", ";", "?", "\\", "\/", "[", "]", "`"], ["，", "。", "：", "；", "？", "、", "、", "【", "】", "·"]];

		//灰度 值
		//[0.33, 0.33, 0.33, 0, 0, 0.33, 0.33, 0.33, 0, 0, 0.33, 0.33, 0.33, 0, 0, 0, 0, 0, 1, 0]
		//[0.3, 0.59, 0.11, 0, 0, 0.3, 0.59, 0.11, 0, 0, 0.3, 0.59, 0.11, 0, 0, 0, 0, 0, 1, 0]
		/**
		 * 在数字中添加千位分隔符
		 *
		 */
		public static function addNumberSeparator(value : int) : String
		{
			var result : String = "";
			while(value>=1000)
			{
				var v : int = value%1000;
				result = ","+fillZeros(v.toString(), 3)+result;
				value = value/1000;
			}
			return result = String(value)+result;
		}

		/**
		 * 计算两个点之前的角度值
		 * @param point1 计算起点坐标
		 * @param point2 计算终点坐标
		 * @return 返回解译值
		 *
		 */
		public static function checkAngle(point1 : Point, point2 : Point) : int
		{
			var angle : int = Math.abs((Math.atan2(point2.y-point1.y, point2.x-point1.x)*180/Math.PI));
			return angle;
		}

		public static function dateToLocalTime(dateStr : String, local : String = "zh_CN") : String
		{
			if(!dateStr)
				return "";
			var date : Date                           = DateFormatter.parseDateString(dateStr);
			var rtnStr : String                       = "";
			var dateTimeFormatter : DateTimeFormatter = new DateTimeFormatter();
			//dateTimeFormatter.dateStyle = DateTimeStyle.CUSTOM;
			if(local=="en_US")
			{
				dateTimeFormatter.dateTimePattern = "EEE, MMM dd, hh:mm a";
			}
			else
			{
				dateTimeFormatter.dateTimePattern = "M月d日,EEEE,ahh:mm";
			}
			dateTimeFormatter.dateStyle = DateTimeStyle.CUSTOM;
			rtnStr = dateTimeFormatter.format(date);
			return rtnStr;
		}

		/**
		 * 取出小时分钟秒 下午06点00分00秒
		 * @param dateStr
		 * @param local 中英文
		 * @param getPM 是否需要上午下午
		 * @param getSecond 是否要求秒
		 * @return
		 *
		 */
		public static function dateToHmTime(dateStr : Object, local : String = "zh_CN", getPM : Boolean = true, getSecond : Boolean = false) : String
		{
			if(!dateStr)
				return "";
			if(dateStr is String)
			{
				var date : Date = DateFormatter.parseDateString(dateStr as String);
			}
			else
			{
				date = dateStr as Date;
			}
			var rtnStr : String                       = "";
			var dateTimeFormatter : DateTimeFormatter = new DateTimeFormatter();
			//dateTimeFormatter.dateStyle = DateTimeStyle.CUSTOM;
			if(local=="en_US")
			{
				if(getPM)
				{
					dateTimeFormatter.dateTimePattern += " a";
					dateTimeFormatter.dateTimePattern = "hh:mm";
				}
				else
				{
					dateTimeFormatter.dateTimePattern = "HH:mm";
				}
				if(getSecond)
				{
					dateTimeFormatter.dateTimePattern += ":ss";
				}
				if(getPM)
				{
					dateTimeFormatter.dateTimePattern += " a";
				}
			}
			else
			{
				if(getPM)
				{
					dateTimeFormatter.dateTimePattern = "a";
					dateTimeFormatter.dateTimePattern = "ahh点mm分";
				}
				else
				{
					dateTimeFormatter.dateTimePattern = "HH点mm分";
				}
				if(getSecond)
				{
					dateTimeFormatter.dateTimePattern += "ss秒";
				}
			}
			dateTimeFormatter.dateStyle = DateTimeStyle.CUSTOM;
			rtnStr = dateTimeFormatter.format(date);
			return rtnStr;
		}

		/**
		 * 取月日
		 * @param dateStr
		 * @param local
		 * @return
		 *
		 */
		public static function dateToMDTime(dateStr : Object, local : String = "zh_CN", getYear : Boolean = false, getWeek : Boolean = false) : String
		{
			if(!dateStr)
				return "";
			if(dateStr is String)
			{
				var date : Date = DateFormatter.parseDateString(dateStr as String);
			}
			else
			{
				date = dateStr as Date;
			}
			var rtnStr : String                       = "";
			var dateTimeFormatter : DateTimeFormatter = new DateTimeFormatter();
			//dateTimeFormatter.dateStyle = DateTimeStyle.CUSTOM;
			if(local=="en_US")
			{
				if(getYear)
				{
					dateTimeFormatter.dateTimePattern = "yyyy-MM-dd";
				}
				else
				{
					dateTimeFormatter.dateTimePattern = "MM-dd";
				}

				if(getWeek)
				{
					dateTimeFormatter.dateTimePattern += " EEEE"
				}
			}
			else
			{
				if(getYear)
				{
					dateTimeFormatter.dateTimePattern = "yyyy年M月d日";
				}
				else
				{
					dateTimeFormatter.dateTimePattern = "M月d日";
				}
				if(getWeek)
				{
					dateTimeFormatter.dateTimePattern += " EEEE"
				}
			}
			dateTimeFormatter.dateStyle = DateTimeStyle.CUSTOM;
			rtnStr = dateTimeFormatter.format(date);
			return rtnStr;
		}

		/**
		 * 将时间转换为字符串
		 *
		 * @param date  日期
		 * @param format        时间格式（hh:mm:ss，h:m:s，hh:mm:ss:ss.s，h:m:s:ss.s，h点m分s秒，H点M分S秒）
		 * @return 转换完毕的字符串
		 *
		 */
		public static function dateToSimpleTime(date : Date, format : String = "hh:mm:ss", utc : Boolean = false) : String
		{
			var h : int     = utc?date.hoursUTC:date.hours;
			var m : int     = utc?date.minutesUTC:date.minutes;
			var s : int     = utc?date.secondsUTC:date.seconds;
			var ms : Number = (utc?date.millisecondsUTC:date.milliseconds)/10;

			switch(format)
			{
				case "hh:mm":
					return fillZeros(h.toString(), 2)+":"+fillZeros(m.toString(), 2);
					break;
				case "h:m":
					return h+":"+m;
					break;
				case "hh:mm:ss":
					return fillZeros(h.toString(), 2)+":"+fillZeros(m.toString(), 2)+":"+fillZeros(s.toString(), 2);
					break;
				case "h:m:s":
					return h+":"+m+":"+s;
					break;
				case "hh:mm:ss:ss.s":
					return fillZeros(h.toString(), 2)+":"+fillZeros(m.toString(), 2)+":"+fillZeros(s.toString(), 2)+":"+ms.toFixed(1);
					break;
				case "h:m:s:ss.s":
					return h+":"+m+":"+s+":"+ms.toFixed(1);
					break;
				case "h点m分s秒":
					return (h?(h+"点"):"")+(m?(m+"分"):"")+s+"秒";
					break;
				case "H点M分S秒":
					return (h?(toChineseNumber(h)+"点"):"")+(m?(toChineseNumber(m)+"分"):"")+toChineseNumber(s)+"秒";
					break;
			}
			return date.toString();
		}

		/**
		 * 将日期转换为字符串
		 *
		 * @param date  日期
		 * @param format        日期格式（yyyy-mm-dd,yyyy-m-d,yyyy年m月d日,Y年M月D日）
		 * @return 转换完毕的字符串
		 *
		 */
		public static function dateToYearString(date : Date, format : String = "yyyy-mm-dd", utc : Boolean = false) : String
		{
			var y : int = utc?date.fullYearUTC:date.fullYear;
			var m : int = utc?date.monthUTC:date.month;
			var d : int = utc?date.dateUTC:date.date;

			switch(format)
			{
				case "mm-dd":
					return fillZeros((m+1).toString(), 2)+"-"+fillZeros(d.toString(), 2);
					break;
				case "yyyy-mm-dd":
					return y+"-"+fillZeros((m+1).toString(), 2)+"-"+fillZeros(d.toString(), 2);
					break;
				case "yyyy-m-d":
					return y+"-"+(m+1).toString()+"-"+d;
					break;
				case "yyyy年m月d日":
					return y+"年"+(m+1).toString()+"月"+d+"日";
					break;
				case "Y年M月D日":
					return toChineseNumber(y)+"年"+toChineseNumber(m+1)+"月"+toChineseNumber(d)+"日";
					break;
			}
			return date.toString();

		}

		/**
		 * 将数字用0补足长度
		 *
		 */
		public static function fillZeros(str : String, len : int, flag : String = "0") : String
		{
			while(str.length<len)
			{
				str = flag+str;
			}
			return str;
		}

		/**
		 * 兼容性从数组或ArrayList等查找对象
		 * @param value 查找值,对比值
		 * @param key 查找对象,属性
		 * @param fromArr 从哪个集合中查找
		 * @return 返回找到的对象,如果没找到返回null
		 *
		 */
		public static function findFromArray(value : Object, key : String, fromArr : Object) : Object
		{
			if(value is String)
			{
				value = (value as String).toUpperCase();
			}

			if(fromArr is ArrayList)
			{
				var i_len : int = fromArr.length;

				for(var i : int = 0; i<i_len; i++)
				{
					var obj : Object = (fromArr as ArrayList).getItemAt(i);

					if(obj[key] is String)
					{
						if((obj[key] as String).toUpperCase()==value)
						{
							return obj;
						}
					}
					else
					{
						if(obj[key]==value)
						{
							return obj;
						}
					}
				}
			}
			else if(fromArr is Array||fromArr is ArrayCollection)
			{
				for each(obj in fromArr)
				{
					if(obj[key] is String)
					{
						if((obj[key] as String).toUpperCase()==value)
						{
							return obj;
						}
					}
					else
					{
						if(obj[key]==value)
						{
							return obj;
						}
					}
				}
			}
			return null;
		}

		/**
		 * 格式化全格式时间 yyyy-MM--dd HH:MM:SS
		 * @param date
		 * @return
		 *
		 */
		public static function formatFullDate(date : Date) : String
		{
			return dateToYearString(date)+" "+dateToSimpleTime(date);
		}

		/**
		 * 日期转换成数据形式年月日
		 * @param d 日期date
		 * @return yyyyMMdd
		 *
		 */
		public static function getDateToNumber(d : Date) : Number
		{
			//trace(toDate(d));
			return Number(d.fullYear.toString()+(d.month+1).toString()+d.date);
		}

		/**
		 * 判断给出的对象是不是gif文件
		 * @param value
		 * @return
		 *
		 */
		public static function isGif(value : *) : Boolean
		{
			var id : String = "";

			if(value is ByteArray)
			{
				var inStream : ByteArray = value as ByteArray;

				for(var i : int = 0; i<3; i++)
				{
					id += String.fromCharCode(inStream.readUnsignedByte());
				}
				inStream.position = 0;

				if(id=="GIF")
				{
					return true;
				}
			}
			else if(value is URLRequest)
			{
				id = (value as URLRequest).url;
			}
			else if(value is String)
			{
				id = value as String;
			}

			if(id.substring(id.length-4).toLocaleLowerCase()==".gif")
			{
				return true;
			}
			return false;
		}

		/**
		 * 转换为汉字数字
		 *
		 */
		public static function toChineseNumber(n : int) : String
		{
			var result : String = "";
			var level : int     = 0;
			while(n>0)
			{
				var v : int = n%10;
				if(level%4==0)
					result = chineseLevel2Mapping[level/4]+result;

				if(v>0)
				{
					if(level%4==1&&v==1)
					{
						result = chineseLevelMapping[level%4]+result;
					}
					else
					{
						result = chineseMapping[v]+chineseLevelMapping[level%4]+result;
					}
				}
				else
				{
					result = chineseMapping[v]+result;
				}
				n = n/10;
				level++;
			}

			return result;
		}

		public static function toChinesePunctuation(v : String, m1 : Boolean = false, m2 : Boolean = false) : String
		{
			var result : String = "";
			for(var i : int = 0; i<v.length; i++)
			{
				var ch : String = v.charAt(i);
				if(ch=="'")
				{
					m1 = !m1;
					result += m1?"‘":"’";
				}
				else if(ch=="\"")
				{
					m2 = !m2;
					result += m2?"“":"”";
				}
				else
				{
					var index : int = (punctuationMapping[0] as Array).indexOf(v.charAt(i));
					if(index!=-1)
						result += punctuationMapping[1][index];
					else
						result += v.charAt(i);
				}
			}
			return result;
		}

		/**
		 * yyyy-MM--dd -----> yyyyMMdd
		 * @param date 转入yyyy-MM--dd格式日期字符串
		 * @param rex 间隔符
		 * @return 数字日期形式yyyyMMdd
		 *
		 */
		public static function yearStrToDateNumber(date : String, rex : String = "-") : Number
		{
			//trace("number:" + date);
			return Number(date.split(rex).join(""));
		}

		/**
		 * 将一个对象转成bytearray,以全用来保存
		 * @param obj 要转化的对象
		 * @param mustRegister 要注册的类对象，反向时需要用到
		 * @return
		 *
		 */
		public static function objectToByteArray(obj : Object, mustRegister : Dictionary = null) : ByteArray
		{
			if(mustRegister)
			{
				for(var paStr : String in mustRegister)
				{
					registerClassAlias(paStr, mustRegister[paStr] as Class);
				}
			}
			var btAry : ByteArray = new ByteArray();
			btAry.writeObject(obj);
			btAry.position = 0;
			return btAry;
		}

		/**
		 * 将一个bytearray转成一个本地实例对象
		 * @param bytes
		 * @param mustRegister
		 * @return
		 *
		 */
		public static function byteArrayToObject(bytes : ByteArray, mustRegister : Dictionary = null) : Object
		{
			if(mustRegister)
			{
				for(var paStr : String in mustRegister)
				{
					registerClassAlias(paStr, mustRegister[paStr] as Class);
				}
			}
			bytes.position = 0;
			return bytes.readObject();
		}

		/**
		 * 将一个对象转换成xml
		 * @param obj 要转换的对象
		 * @param qn 根节点名称,默认为root
		 * @return 返回xml对象
		 *
		 */
		public static function objectToXML(obj : Object, qn : String = "root") : XML
		{
			var qName : QName                       = new QName(qn);
			var xmlDocument : XMLDocument           = new XMLDocument();
			var simpleXMLEncoder : SimpleXMLEncoder = new SimpleXMLEncoder(xmlDocument);
			var xmlNode : XMLNode                   = simpleXMLEncoder.encodeValue(obj, qName, xmlDocument);
			var xml : XML                           = new XML(xmlDocument.toString());
			return xml;
		}

		/**
		 * 读取一个xml文件并转化成xml
		 * @param filepath 文件的详细路径,必须是一个文件
		 */
		public static function readXMLFile(filePath : String) : XML
		{
			var file : File = new File(filePath);

			if(file.exists&&!file.isDirectory&&file.extension=="xml")
			{
				var fileStream : FileStream = new FileStream();
				fileStream.open(file, FileMode.READ);
				var bytes : ByteArray       = new ByteArray;
				fileStream.readBytes(bytes);
				fileStream.close();
				fileStream = null;
				file = null;
				return XML(bytes);
			}
			return null;
		}

		/**
		 * 保存一个xml文件
		 * @param filepath 文件的详细路径,必须是一个文件
		 * @param xml 要保存的xml内容
		 *
		 */
		public static function saveXMLFile(filePath : String, xml : XML) : void
		{
			var file : File = new File(filePath);

			if(file.extension=="xml")
			{
				var fileStream : FileStream = new FileStream();
				fileStream.open(file, FileMode.WRITE);
				fileStream.writeUTFBytes(xml.toString());
				fileStream.close();
				fileStream = null;
				file = null;
			}

		}

		//head=>序列的开头
		//tail=>序列的结尾
		public function quickSort(array : Array, head : int, tail : int) : void
		{
			//TODO 待研快速排序法
			if(head>tail)
			{
				return;
			}
			//i,j指向头和尾巴   
			var i : int        = head;
			var j : int        = tail;
			var iPivot : Array = array;
			/**< 选取枢轴 */
			while(i<j)
			{
				//使用j,从序列最右端开始扫描,直到遇到比枢轴小的数 
				while((i<j)&&(iPivot<=array[j]))
				{
					j--;
				}
				//交换位置        
				if(i<j)
				{
					array[i++] = array[j];
				}
				//使用i,从序列最左端开始扫描,直到遇到比枢轴小的数枢轴大的数       
				while((i<j)&&(array<=iPivot))
				{
					i++;
				}
				//交换位置        
				if(i<j)
				{
					array[j--] = array;
				}
			}
			//最后填入枢轴位置    
			array[j] = iPivot;
			//这里就是对枢轴两边序列进行排序的递归调用 
			quickSort(array, head, i-1);
			quickSort(array, i+1, tail);
		}

		/**
		 * 打印一个对象及其所有子对象,将所有值和属性名称打印出来,格式为funame.prop = value;
		 * @param info
		 * @param funame
		 *
		 */
		public static function traceInfo(info : Object, funame : String = "") : void
		{
			if(info)
			{
				for(var name : String in info)
				{
					trace(funame+"."+name+" = "+info[name]);
					traceInfo(info[name], funame+"."+name);
				}
			}
		}
	}
}
